<template>
  <div id="tableSearch">
    <el-card class="search" shadow="hover">
      <div slot="header" class="card-title flex-a-center">
        <i class="el-icon el-icon-search" />
        筛选查询
        <div class="operate">
          <el-button @click="onSearchSubmit" type="primary" size="medium" native-type="submit">查询</el-button>
          <el-button @click="onSearchReset" type="default" size="medium" native-type="reset">重置</el-button>
        </div>
      </div>
      <slot name="table-search"></slot>
      <el-form
        inline
        label-width="8em"
        size="medium"
      >
        <el-form-item
          v-for="item in searchColumns"
          :key="item.key"
          :label="`${item.title}：`"
        >
          <el-date-picker
            v-if="item.type === 'time'"
            v-model="searchModelData[item.key]"
            type="datetimerange"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            value-format="yyyy-MM-dd HH:mm:ss"
            format="yyyy-MM-dd HH:mm:ss"
          >
          </el-date-picker>
          <el-select
            v-else-if="item.type === 'select'"
            :value="searchModelData[item.key] || ''"
            @input="$set(searchModelData, item.key, $event)"
            :placeholder="`请选择${item.title}`"
          >
            <el-option
              v-for="option in item.options"
              :key="option.value || 'all'"
              :value="option.value"
              :label="option.label"
            ></el-option>
          </el-select>
          <el-input
            v-else
            v-model="searchModelData[item.key]"
            :placeholder="`请输入${item.title}`"
          ></el-input>
        </el-form-item>
      </el-form>
    </el-card>
    <br />
    <template v-if="tabsOptions">
      <div class="tabs">
        <el-button
          v-for="item in tabsOptions.list"
          :key="item.code"
          :type="tabState.currentCode === item.code ? 'primary' : 'default'"
          @click="onSwitchTab(item)"
        >{{item.desc}}(<span class="number">{{tabsOptions.data[item.code]}}</span>)</el-button>
      </div>
      <br />
    </template>
    <el-card
      class="table"
      shadow="hover"
      body-style="padding: 0"
    >
      <div slot="header" class="card-title flex-a-center">
        <i class="el-icon el-icon-notebook-2" />
        {{title}}
        <slot name="table-title"></slot>
      </div>
      <el-table
        v-loading="tableState.loading"
        :data="tableState.data"
        stripe
        style="width: 100%"
        @selection-change="handleSelectionChange"
      >
        <!-- header-cell-style="background-color: #f5f5f5;color: #333;font-weight: bold;text-align:center" -->
        <el-table-column v-if="selection" align="center" type="selection" width="50"></el-table-column>
        <el-table-column
          v-for="item in tableColumns"
          :key="item.dataIndex"
          :prop="item.dataIndex"
          :label="item.title"
          :align="item.align || 'center'"
          :width="item.width || null"
        >
          <template slot-scope="scope">
            <slot :name="item.dataIndex" v-bind="scope">
              {{scope.row[item.dataIndex] || '-'}}
            </slot>
          </template>
        </el-table-column>

      </el-table>
      <div class="pagination">
        <el-pagination
          background
          layout="total, sizes, prev, pager, next, jumper"
          :current-page="tableState.pageIndex"
          :page-sizes="[10, 20, 30, 40]"
          :page-size="tableState.pageSize"
          :total="tableState.total"
          @size-change="onPageSizeChange"
          @current-change="onPageIndexChange"
        >
        </el-pagination>
      </div>
    </el-card>
  </div>
</template>

<script>
// eslint-disable-next-line no-unused-vars
import { defineComponent, computed, reactive, ref, getCurrentInstance, onMounted } from '@vue/composition-api'
export default defineComponent({
  props: {
    columns: Array,
    api: {
      type: Function,
      default: () => ({ list: [], total: 0 }),
    },
    title: String,
    tabsOptions: Object,
    selection: Boolean,
  },
  setup (props, ctx) {
    const vm = getCurrentInstance()
    const searchParams = {}
    const searchModelData = reactive({ })
    const searchColumns = computed(() => {
      const {
        columns,
      } = props
      const getType = (search) => {
        const { column, type } = search
        if (type) {
          return type
        } else if (/time/i.test(column.dataIndex)) {
          return 'time'
        }
      }
      const _searchColumns = []
      columns.forEach(column => {
        if (column.search) {
          const search = typeof column.search === 'object' ? column.search : { }
          search.key = search.key ? search.key.toString() : column.dataIndex
          search.column = column
          search.type = getType(search)
          search.title = search.title || column.title
          _searchColumns.push(search)
          if (vm.$route.query[search.key] && !searchModelData[search.key]) {
            searchModelData[search.key] = searchParams[search.key] = vm.$route.query[search.key].trim()
          }
        }
      })
      return _searchColumns.sort((a, b) => (a.sort || 1) - (b.sort || 1))
    })
    const onSearchReset = () => {
      Object.keys(searchModelData).forEach(key => {
        searchModelData[key] = Array.isArray(searchModelData[key]) ? [] : ''
      })
    }
    const onSearchSubmit = () => {
      Object.keys(searchModelData).forEach(key => {
        const value = searchModelData[key]
        if (Array.isArray(value)) {
          key.split(',').forEach((key, index) => {
            searchParams[key] = value[index]
          })
        } else {
          searchParams[key] = value
        }
      })
      tableState.pageIndex = 1
      getList()
    }

    // table
    const tableState = reactive({
      pageIndex: 1,
      pageSize: 10,
      loading: false,
      data: [],
      total: 0,
    })
    const tableColumns = computed(() => {
      return props.columns.filter(column => !column.hide)
    })

    const onPageSizeChange = val => {
      tableState.pageSize = val
      tableState.pageIndex = 1
      getList()
    }
    const onPageIndexChange = val => {
      tableState.pageIndex = val
      getList()
    }

    const getList = async () => {
      tableState.loading = true
      if (props.tabsOptions)
        searchParams[props.tabsOptions.searchKey] = tabState.currentCode === 'all' ? null : tabState.currentCode
      const { list, total } = await props.api(tableState.pageIndex, tableState.pageSize, { ...searchParams })
      tableState.loading = false
      tableState.data = list
      tableState.total = total
      // console.log(list, total)
    }
    const reload = pageIndex => {
      if (props.tabsOptions)
        tabState.pageIndex = pageIndex || tabState.pageIndex
      getList()
    }

    // tabs
    const tabState = reactive({
      currentCode:  props.tabsOptions ? (vm.$route.query[props.tabsOptions.searchKey] || props.tabsOptions.list[0].code) : '',
    })
    const onSwitchTab = item => {
      tabState.currentCode = item.code
      tableState.pageIndex = 1
      getList()
    }

    onMounted(() => {
      getList()
    })

    const selectionItems = ref([])
    const handleSelectionChange = (val) => {
      selectionItems.value = val
      vm.$emit('selection-change', val)
    }

    return {
      searchColumns,
      searchModelData,
      onSearchReset,
      onSearchSubmit,
      tableState,
      tableColumns,
      onPageSizeChange,
      onPageIndexChange,
      tabState,
      onSwitchTab,
      reload,
      selectionItems,
      handleSelectionChange,
    }
  },
})
</script>

<style lang="scss">
#tableSearch {
  .el-card__header {
    background-color: #f5f5f5;
  }
  .card-title {
    .el-icon {
      margin-right: 5px;
      font-size: 1.2em;
    }
    .operate {
      flex: 1;
      text-align: right;
    }
  }
  .search .el-card__header{
    padding: 10px 20px;
  }
  .tabs .el-button--default .number {
    color: red;
  }

  .pagination {
    text-align: right;
    padding: 12px;
  }
}
</style>
